#light

open Microsoft.FSharp.Control.Mailboxes

type internal msg = Increment of int | Fetch of AsyncReplyChannel<int> | Stop

type CountingAgent() =
    let counter = MailboxProcessor.Start(fun inbox ->
        let rec loop(n) =
            async { let! msg = inbox.Receive()
                    match msg with
                    | Increment m        -> return! loop(n+m)
                    | Stop               -> return ()
                    | Fetch replyChannel ->
                        do replyChannel.Reply(n)
                        return! loop(n) }
        loop(0))
        
    member a.Increment(n) = counter.Post(Increment(n))
    member a.Stop() = counter.Post(Stop)
    member a.Fetch() = counter.PostAndReply(fun replyChannel -> Fetch(replyChannel))
    
let counter = CountingAgent()

print_endline "Incrementing by 1..."
counter.Increment(1)

printfn "-> %d" (counter.Fetch())

print_endline "Incrementing by 2..."
counter.Increment(2)

printfn "-> %d" (counter.Fetch())

counter.Stop()
